package com.ruoyi.ems.utils;
import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class SignatureUtil {
    private static final String apiKey = "a367b552cfe347cc88e883158c0f7482"; // API密钥



    public static String generateSign(Map<String, String> params,String apiKey) {
        // 先对map的键进行排序
        String result = params.entrySet().stream()
                .sorted(Map.Entry.comparingByKey())
                .map(entry -> entry.getKey() + entry.getValue())
                .collect(Collectors.joining());

        // 添加API Key 
        result += apiKey;

        System.out.println("签名原串"+result);

        // 计算MD5值
        return md5(result);
    }

    public static String md5(String s) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] array = md.digest(s.getBytes());
            StringBuilder sb = new StringBuilder();
            for (byte item : array) {
                sb.append(Integer.toHexString((item & 0xFF) | 0x100), 1, 3);
            }
            return sb.toString().toLowerCase();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }






    public static String sortAndJoinParams(Map<String, String> params) {
        List<Map.Entry<String, String>> sortedParams = new ArrayList<>(params.entrySet());
        sortedParams.removeIf(entry -> entry.getValue().isEmpty());
        sortedParams.sort(Comparator.comparing(Map.Entry::getKey));

        StringBuilder paramBuilder = new StringBuilder();
        for (Map.Entry<String, String> entry : sortedParams) {
            paramBuilder.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
        }

        String paramString = paramBuilder.toString();
        if (!paramString.isEmpty()) {
            paramString = paramString.substring(0, paramString.length() - 1);
        }

        return paramString;
    }




    /*
        1、将所有业务请求参数值不为空的字段，按照参数名字典序排列，中间用&号连
        接，例如 k1=v1&k2=v2&k3=v3
        2、在第一步获取到的字符串结尾拼接上签名秘钥 key，例如：
        k1=v1&k2=v2&k3=v3&key=xxxxx
        3、将连接后的字符串采用国密 sm3 算法生成签名，并将结果转为大写
     */
    public static String generateSignature(Map<String, Object> params, String secretKey) throws Exception {
        List<Map.Entry<String, Object>> sortedParams = new ArrayList<>(params.entrySet());
        sortedParams.removeIf(entry -> String.valueOf(entry.getValue()).isEmpty());
        sortedParams.sort(Comparator.comparing(Map.Entry::getKey));

        StringBuilder paramBuilder = new StringBuilder();
        for (Map.Entry<String, Object> entry : sortedParams) {
            paramBuilder.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
        }
        paramBuilder.append("key=").append(secretKey);

        String paramString = paramBuilder.toString();

        Security.addProvider(new BouncyCastleProvider());
        SM3Digest digest = new SM3Digest();
        byte[] messageHash = paramString.getBytes(StandardCharsets.UTF_8);
        digest.update(messageHash, 0, messageHash.length);
        byte[] sign = new byte[digest.getDigestSize()];
        digest.doFinal(sign, 0);

        return bytesToHexString(sign).toUpperCase();
    }


    private static String bytesToHexString(byte[] bytes) {
        StringBuilder hexString = new StringBuilder();
        for (byte b : bytes) {
            String hex = Integer.toHexString(0xFF & b);
            if (hex.length() == 1) {
                hexString.append('0');
            }
            hexString.append(hex);
        }
        return hexString.toString();
    }





}
